#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define BUF_SIZE 1024
//#define HOST "coronavirus-tracker-api.herokuapp.com"
//#define URI "/v2/latest"
#define HOST "downloads.raspberrypi.org"
#define URI "/imager/imager.exe"
//#define HOST "www.baidu.com"
//#define URI "/"

int parse_status(char* line)
{
	char protocol[10];
	int code;
	char reason[100];
	
	sscanf(line, "%9s %3d %99[a-zA-Z ]", protocol, &code, reason);

	printf("protocol = %s\n", protocol);
	printf("code = %d\n", code);
	printf("reason = %s\n", reason);

	return code;
}

void print_field(char* line)
{
	char key[100];
	char value[512];
	sscanf(line, "%99[^:]: %511[^\r]", key, value);
	printf("%s = %s\n", key, value);
}

int main()
{
	struct addrinfo hints;
	struct addrinfo * result, * rp;
	int err;
	int sfd;
	FILE* sfp;
	char buf[BUF_SIZE];

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	err = getaddrinfo(HOST, "80", &hints, &result);
	if (err) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
		exit(EXIT_FAILURE);
	}

	for (rp = result; rp != NULL; rp = rp->ai_next) {
		sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
		if (sfd < 0) {
			continue;
		}

		if (connect(sfd, rp->ai_addr, rp->ai_addrlen) == 0) {
			printf("server connected\n");
			break;
		}

		perror("connect");

		close(sfd);
	}
	
	if (!rp) {
		exit(EXIT_FAILURE);
	}

	freeaddrinfo(result);

	sfp = fdopen(sfd, "r+");
	if (!sfp) {
		perror("fdopen");
		exit(EXIT_FAILURE);
	}

	fprintf(sfp, "GET "URI" HTTP/1.1\r\n");
	fprintf(sfp, "Host: "HOST"\r\n");
	fprintf(sfp, "Connection: close\r\n");
	fprintf(sfp, "\r\n");

	//处理响应报文状态行
	fgets(buf, BUF_SIZE, sfp);
	if (parse_status(buf) != 200) {
		return 1;
	}

	//处理响应头，读取到空行后结束循环
	while(fgets(buf, BUF_SIZE, sfp) && strlen(buf) > 2) {
		print_field(buf);
	}

	//处理响应内容
	size_t n = 0;
	while ((n = fread(buf, 1, BUF_SIZE, sfp))) {
		fwrite(buf, 1, n, stdout);
	}

	fclose(sfp);
	
	return 0;
}
